<template>
   <div>
    <Button type="link" @click="handleAddConfig" class="add-btn" my-5>+ 新增{{ interfaceType === 'BEFORE' ? '前置' :
        '压测' }}接口</Button>
    <Collapse v-model:activeKey="collapseActiveKey" style="background: transparent" v-if="isContainsList()">

        <template #expandIcon="{ isActive }">
            <CaretRightOutlined :rotate="isActive ? 90 : 0" style="color: #f5f5f5" />
        </template>

        <CollapsePanel :key="index + 1" :header="item.name ? item.name : `${interfaceType === 'BEFORE' ? '前置' :
            '压测'}接口名称`" v-for="(item, index) in formModel.stressCaseDetailSaveReqList"
            v-show="item.interfaceType === interfaceType">
            <template #extra>
                <DeleteOutlined text-red @click="handleDeleteConfig(index, item.interfaceType)" style="font-size: 20px;" />
            </template>
            <Form.Item label="采样器配置：">
                <div b="~ solid #707070 op-75" mx-8 rounded p="x-6 t-6">
                    <Row :gutter="40">
                        <Col :span="6">
                        <Form.Item label="协议：">
                            <Input v-model:value="item.protocol" />
                        </Form.Item>
                        </Col>
                        <Col :span="6">
                        <Form.Item label="IP：">
                            <Input v-model:value="item.domain" />
                        </Form.Item>
                        </Col>
                        <Col :span="6">
                        <Form.Item label="端口：">
                            <Input v-model:value="item.port" />
                        </Form.Item>
                        </Col>
                        <Col :span="6">
                        <Form.Item label="字符编码：">
                            <Input v-model:value="item.contentEncoding" />
                        </Form.Item>
                        </Col>
                    </Row>
                    <Row :gutter="40">
                        <Col :span="12">
                        <Form.Item label="名称：">
                            <Input v-model:value="item.name" />
                        </Form.Item>
                        </Col>
                        <Col :span="12">
                        <Form.Item label="描述：">
                            <Input v-model:value="item.description" />
                        </Form.Item>
                        </Col>
                    </Row>
                    <Row :gutter="40">
                        <Col :span="12">
                        <Form.Item label="路径：">
                            <Input v-model:value="item.path" />
                        </Form.Item>
                        </Col>
                        <Col :span="12">
                        <FormItemMethod v-model:method="item.method" />
                        </Col>
                    </Row>
                    <br />
                    <div>
                        <RequestConfig :ref="el => getRequestConfigRef(el, item.index, item.interfaceType)"
                            v-model:bodyType="item.bodyType" is-stress-test :is-stress-test-before="interfaceType === 'BEFORE'"
                            key-name="key" />
                    </div>
                </div>
            </Form.Item>
            <Form.Item label="开启断言：">
                <Switch v-model:checked="item.formModelExpand.assertion" />
            </Form.Item>
            <EditableTable v-if="item.formModelExpand.assertion"
                v-model:data-source-proxy="item.formModelExpand.assertionData" :columns="assertionColumns"
                :custom-fields="['action', 'from']" @add-data="handleAddAssertion(index)">
                <template #bodyCell="{ column, record, isEdit, value }">
                    <span v-if="!isEdit &&
                        ['action', 'from'].includes(column.key?.toString() ?? '')
                        ">{{ value }}</span>

                    <template v-if="column.key === 'action' && isEdit">
                        <Select v-model:value="record[column.key!]">
                            <Select.Option v-for="item in fetchDictListData?.stress_assert_action" :key="item.id"
                                :value="item.value">
                                <Tooltip :title="item.remark">
                                    {{ item.name }}
                                </Tooltip>
                            </Select.Option>
                        </Select>
                    </template>

                    <template v-if="column.key === 'from' && isEdit">
                        <Select v-model:value="record[column.key!]">
                            <Select.Option v-for="item in fetchDictListData?.stress_assert_from" :key="item.id"
                                :value="item.value">
                                <Tooltip :title="item.remark">
                                    {{ item.name }}
                                </Tooltip>
                            </Select.Option>
                        </Select>
                    </template>
                </template>
            </EditableTable>

            <template v-if="interfaceType === 'ORDINARY'">
                <Form.Item label="开启参数化：">
                    <Switch v-model:checked="item.formModelExpand.relation" />
                </Form.Item>

                <EditableTable v-if="item.formModelExpand.relation"
                    v-model:data-source-proxy="item.formModelExpand.relationData" :columns="relationColumns" :custom-fields="[
                        'ignoreFirstLine',
                        'recycle',
                        'fileUpload',
                        'sourceType',
                    ]" @add-data="handleAddRelation(index)">
                    <template #bodyCell="{ column, isEdit, record, currentEditableInstance }">
                        <template v-if="column.key === 'fileUpload'">
                            <UploadFile v-if="isEdit" :show-url="record?.['remoteFilePath']" @change="
                                $event.file.response &&
                                (currentEditableInstance.remoteFilePath =
                                    $event.file.response.data)
                                ">
                                <Button type="link">{{
                                    !!record?.['remoteFilePath'] ? '已上传' : '上传文件'
                                }}</Button>
                            </UploadFile>
                            <span v-else>{{
                                !!record?.['remoteFilePath'] ? '已上传' : '未上传'
                            }}</span>
                        </template>
                    </template>
                </EditableTable>
            </template>
             <StressTestSampler v-model:save-req="formModel.stressCaseDetailSaveReqList[index]"/>

        </CollapsePanel>

    </Collapse>
   </div>
</template>

<script lang="ts" setup>
import {
    type IStressCase,
    type IStressCaseAssertion,
    type IStressCaseRelation,
    type IStressCaseThreadGroupConfig,
    type IStressCaseDetailSaveReq,
    defaultWithIStressCase,
    defaultWithIStressCaseAssertion,
    defaultWithIStressCaseRelation,
    defaultWithIStressCaseThreadGroupConfig,
    defaultWithIStressCaseDetailSaveReq
} from '~/types/apis/stress-case'
import type { ComponentExposed } from 'vue-component-type-helpers'
import {
    Button,
    Form,
    Input,
    Select,
    Switch,
    Tooltip,
    message,
    Row,
    Col,
    Collapse,
    CollapsePanel
} from 'ant-design-vue'
import {
    CaretRightOutlined,
    DeleteOutlined
} from '@ant-design/icons-vue';
import type RequestConfigVue from '~/components/NewOrEdit/RequestConfig.vue'
import type { ColumnsType } from 'ant-design-vue/es/table'
import type StressTestSampler from '~/components/NewOrEdit/StressTestSampler.vue'


const props = withDefaults(
    defineProps<{
        interfaceType: string
    }>(),
    {
        interfaceType: 'ORDINARY',
    },
)

interface FormModelType {
    stressCaseDetailSaveReqList: IStressCaseDetailSaveReq[]
}

const formModel = defineModel<FormModelType>('formModel', { required: true })

const formModelExpand = reactive<{
    relation: boolean
    assertion: boolean
    relationData: IStressCaseRelation[]
    assertionData: IStressCaseAssertion[]
    threadGroupConfig: IStressCaseThreadGroupConfig
}>({
    relation: false,
    assertion: false,
    relationData: [],
    assertionData: [],
    threadGroupConfig: { ...defaultWithIStressCaseThreadGroupConfig },
})

let stressCaseDetailSaveReq = Object.assign({}, defaultWithIStressCaseDetailSaveReq)
const beforeRequestConfigRefList = ref<Array<{ el: ComponentExposed<typeof RequestConfigVue>, index: number }>>([])
const ordinaryRequestConfigRefList = ref<Array<{ el: ComponentExposed<typeof RequestConfigVue>, index: number }>>([])
const getRequestConfigRef = (el: ComponentExposed<typeof RequestConfigVue>, index: number, interfaceType: string) => {
    const isBeforeContains = beforeRequestConfigRefList.value.some((item: { index: number }) => item.index === index)
    const isOrdinaryContains = ordinaryRequestConfigRefList.value.some((item: { index: number }) => item.index === index)

    if (el) {
        const refData = {
            el,
            index
        }
        if (!isBeforeContains && interfaceType === 'BEFORE') {
            beforeRequestConfigRefList.value.push(
                refData
            )
            // 获取折叠面板的请求配置值  因为默认第一个折叠面板打开只能获取到第一个requestConfig组件的dom节点,在展开其他折叠面板时，需重新赋值上去
            // bug点： 之前是只放在el判断里导致每次切换请求体时导致重置了所有填写请求参数，故只有在新增时才会调用此参数
            requestDeserialize(el, formModel.value.stressCaseDetailSaveReqList[index])
        }
        if (!isOrdinaryContains && interfaceType === 'ORDINARY') {
            ordinaryRequestConfigRefList.value.push(
                refData
            )
            // 同上
            requestDeserialize(el, formModel.value.stressCaseDetailSaveReqList[index])
        }
    }



}

const relationColumns: ColumnsType = [
    {
        title: '名称',
        dataIndex: 'name',
        key: 'name',
        align: 'center',
    },
    {
        title: '文件类型',
        dataIndex: 'sourceType',
        key: 'sourceType',
        align: 'center',
    },
    {
        title: '分隔符',
        dataIndex: 'delimiter',
        key: 'delimiter',
        align: 'center',
    },
    {
        title: '是否忽略首行',
        dataIndex: 'ignoreFirstLine',
        key: 'ignoreFirstLine',
        align: 'center',
    },
    {
        title: '循环读取',
        dataIndex: 'recycle',
        key: 'recycle',
        align: 'center',
    },
    {
        title: '变量名称 (逗号分割)',
        dataIndex: 'variableNames',
        key: 'variableNames',
        align: 'center',
    },
    {
        title: '文件上传',
        dataIndex: 'fileUpload',
        key: 'fileUpload',
        align: 'center',
    },
    {
        title: '操作',
        dataIndex: 'operator',
        align: 'center',
        key: 'operator',
    },
]

const assertionColumns: ColumnsType = [
    {
        title: '断言名称',
        dataIndex: 'name',
        key: 'name',
        align: 'center',
    },
    {
        title: '断言操作',
        dataIndex: 'action',
        key: 'action',
        align: 'center',
    },
    {
        title: '断言来源',
        dataIndex: 'from',
        key: 'from',
        align: 'center',
    },
    {
        title: '断言值',
        dataIndex: 'value',
        key: 'value',
        align: 'center',
    },
    {
        title: '操作',
        dataIndex: 'operator',
        align: 'center',
        key: 'operator',
    },
]

const isContainsList = () => {
   return formModel.value.stressCaseDetailSaveReqList.filter((item: IStressCaseDetailSaveReq) => item.interfaceType == props.interfaceType).length > 0
}

function handleAddRelation(index: number) {
    if (formModel.value.stressSourceType.toUpperCase() === 'SIMPLE') {
        formModel.value.stressCaseDetailSaveReqList[index].formModelExpand.relationData.push({ ...defaultWithIStressCaseRelation })
    } else {
        formModelExpand.relationData.push({ ...defaultWithIStressCaseRelation })
    }
}

function handleAddAssertion(index: number) {
    if (formModel.value.stressSourceType.toUpperCase() === 'SIMPLE') {
        formModel.value.stressCaseDetailSaveReqList[index].formModelExpand.assertionData.push({ ...defaultWithIStressCaseAssertion })
    } else {
        formModelExpand.assertionData.push({ ...defaultWithIStressCaseAssertion })
    }
}

const requestDeserialize = (el: ComponentExposed<typeof RequestConfigVue>, requestConfigData: IStressCaseDetailSaveReq) => {
    el.deserialize({
        body: requestConfigData.body,
        query: requestConfigData.query,
        header: requestConfigData.header,
        bodyType: requestConfigData.bodyType,
        relation: requestConfigData.relationParam ?? ''
    })
}

const collapseActiveKey = ref([]);

const handleAddConfig = () => {
    const formModelExpand2 = JSON.parse(JSON.stringify(formModelExpand))
    stressCaseDetailSaveReq = Object.assign({}, defaultWithIStressCaseDetailSaveReq)
    stressCaseDetailSaveReq.formModelExpand = formModelExpand2
    stressCaseDetailSaveReq.interfaceType = props.interfaceType
    stressCaseDetailSaveReq.index = formModel.value.stressCaseDetailSaveReqList.length
    formModel.value.stressCaseDetailSaveReqList.push(stressCaseDetailSaveReq)
}

const handleDeleteConfig = (index: number, interfaceType: string) => {
    if (formModel.value.stressCaseDetailSaveReqList.length === 1) {
        return message.warn('至少保留一条配置信息')
    }
    formModel.value.stressCaseDetailSaveReqList.splice(index, 1)
    if (interfaceType === 'BEFORE') {
        beforeRequestConfigRefList.value = beforeRequestConfigRefList.value.filter((item: { index: number }) => {
            return item.index === index
        })
    }
    if (interfaceType === 'ORDINARY') {
        ordinaryRequestConfigRefList.value = ordinaryRequestConfigRefList.value.filter((item: { index: number }) => {
            return item.index === index
        })
    }

}


defineExpose({
    beforeRequestConfigRefList,
    ordinaryRequestConfigRefList,
    requestDeserialize,
})

</script>

<style lang="scss" scoped></style>